/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package TimeRecording.tables;

import TimeRecording.business.DaisyChainUtilities;
import TimeRecording.business.DateRange;
import TimeRecording.business.DateRangeable;
import TimeRecording.enums.WeeklyTimeStatus;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.PostLoad;
import javax.persistence.Table;
import javax.persistence.Transient;

/**
 *
 * @author david
 */
@Entity
@Table(name = "weekly_time")
@NamedQueries({
    @NamedQuery(
            name = "WeeklyTime.findAll",
            query = "SELECT w " +
                    "FROM WeeklyTime w"),
    @NamedQuery(
            name = "WeeklyTime.findByEmployeeId",
            query = "SELECT w " +
                    "FROM WeeklyTime w " +
                    "WHERE w.weeklyTimePK.employeeId = :employeeId"),
    @NamedQuery(
            name = "WeeklyTime.findByWeekCommencing",
            query = "SELECT w " +
                    "FROM WeeklyTime w " +
                    "WHERE w.weeklyTimePK.weekCommencing = :weekCommencing"),
    @NamedQuery(
            name = "WeeklyTime.findByDateRange",
            query = "SELECT w " +
                    "FROM WeeklyTime w " +
                    "WHERE w.weeklyTimePK.weekCommencing >= :startDate AND " +
                          "w.weeklyTimePK.weekCommencing <= :endDate"),
    @NamedQuery(
            name = "WeeklyTime.findByEmployeeAndDateRange",
            query = "SELECT w " +
                    "FROM WeeklyTime w " +
                    "WHERE w.weeklyTimePK.employeeId = :employeeId AND " +
                          "w.weeklyTimePK.weekCommencing <= :endDate AND " +
                          "w.weeklyTimePK.weekCommencing >= :startDate"),
    @NamedQuery(
            name = "WeeklyTime.findByEmployeeAndStatuses",
            query = "SELECT w " +
                    "FROM WeeklyTime w " +
                    "WHERE w.weeklyTimePK.employeeId = :employeeId AND " +
                          "w.status IN (:status1, :status2, :status3, :status4)"),
    @NamedQuery(
            name = "WeeklyTime.findByStatuses",
            query = "SELECT w " +
                    "FROM WeeklyTime w " +
                    "WHERE w.status IN (:status1, :status2, :status3, :status4)")})

public class WeeklyTime implements Serializable, DateRangeable {

public final static String BY_EMPLOYEE_AND_DATE_RANGE =
            "WeeklyTime.findByEmployeeAndDateRange";

    private static final long serialVersionUID = 1L;

    private static final Collection<WeeklyTimeStatus> ACTIVE_STATUSES =
            Arrays.asList(new WeeklyTimeStatus[] {
                    WeeklyTimeStatus.APPROVED,
                    WeeklyTimeStatus.PREPARATION,
                    WeeklyTimeStatus.REJECTED,
                    WeeklyTimeStatus.SUBMITTED });

    @Transient
    private Date weekEnding;

    // <editor-fold defaultstate="collapsed" desc="Property Change Support">
    @Transient
    private PropertyChangeSupport changeSupport = new PropertyChangeSupport(this);

    public void addPropertyChangeListener(PropertyChangeListener listener) {
        changeSupport.addPropertyChangeListener(listener);
    }

    public void removePropertyChangeListener(PropertyChangeListener listener) {
        changeSupport.removePropertyChangeListener(listener);
    } // </editor-fold>

    @EmbeddedId
    protected WeeklyTimePK weeklyTimePK;

    // <editor-fold defaultstate="collapsed" desc="Monday Figures">
    @Embedded
    @AttributeOverrides({
        @AttributeOverride(name="clocked", column=@Column(name="monday_clocked")),
        @AttributeOverride(name="entered", column=@Column(name="monday_entered")),
        @AttributeOverride(name="sickness", column=@Column(name="monday_sickness")),
        @AttributeOverride(name="holiday", column=@Column(name="monday_holiday")),
        @AttributeOverride(name="estimated", column=@Column(name="monday_estimated")),

        @AttributeOverride(name="fixedExpected", column=@Column(name="monday_fixed_expected")),
        @AttributeOverride(name="fixedRecorded", column=@Column(name="monday_fixed_recorded")),
        @AttributeOverride(name="fixedSickness", column=@Column(name="monday_fixed_sickness")),
        @AttributeOverride(name="fixedHoliday", column=@Column(name="monday_fixed_holiday")),

        @AttributeOverride(name="semiFlexiExpected", column=@Column(name="monday_semi_flexi_expected")),
        @AttributeOverride(name="semiFlexiRecorded", column=@Column(name="monday_semi_flexi_recorded")),
        @AttributeOverride(name="semiFlexiSickness", column=@Column(name="monday_semi_flexi_sickness")),
        @AttributeOverride(name="semiFlexiHoliday", column=@Column(name="monday_semi_flexi_holiday")),

        @AttributeOverride(name="flexiExpected", column=@Column(name="monday_flexi_expected")),
        @AttributeOverride(name="flexiRecorded", column=@Column(name="monday_flexi_recorded")),
        @AttributeOverride(name="flexiSickness", column=@Column(name="monday_flexi_sickness")),
        @AttributeOverride(name="flexiHoliday", column=@Column(name="monday_flexi_holiday")),

        @AttributeOverride(name="sessionExpected", column=@Column(name="monday_session_expected")),
        @AttributeOverride(name="sessionRecorded", column=@Column(name="monday_session_recorded")),
        @AttributeOverride(name="sessionSickness", column=@Column(name="monday_session_sickness")),
        @AttributeOverride(name="sessionHoliday", column=@Column(name="monday_session_holiday")),

        @AttributeOverride(name="adHocRecorded", column=@Column(name="monday_ad_hoc_recorded")),
        @AttributeOverride(name="adHocSickness", column=@Column(name="monday_ad_hoc_sickness")),
        @AttributeOverride(name="adHocHoliday", column=@Column(name="monday_ad_hoc_holiday"))
    })
    private AllocationOfHours monday;

    public AllocationOfHours getMonday() {
        return monday;
    }

    public void setMonday(AllocationOfHours monday) {
        AllocationOfHours oldMonday = this.monday;
        this.monday = monday;
        changeSupport.firePropertyChange("monday", oldMonday, monday);
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Tuesday Figures">
    @Embedded
    @AttributeOverrides({
        @AttributeOverride(name="clocked", column=@Column(name="tuesday_clocked")),
        @AttributeOverride(name="entered", column=@Column(name="tuesday_entered")),
        @AttributeOverride(name="sickness", column=@Column(name="tuesday_sickness")),
        @AttributeOverride(name="holiday", column=@Column(name="tuesday_holiday")),
        @AttributeOverride(name="estimated", column=@Column(name="tuesday_estimated")),

        @AttributeOverride(name="fixedExpected", column=@Column(name="tuesday_fixed_expected")),
        @AttributeOverride(name="fixedRecorded", column=@Column(name="tuesday_fixed_recorded")),
        @AttributeOverride(name="fixedSickness", column=@Column(name="tuesday_fixed_sickness")),
        @AttributeOverride(name="fixedHoliday", column=@Column(name="tuesday_fixed_holiday")),

        @AttributeOverride(name="semiFlexiExpected", column=@Column(name="tuesday_semi_flexi_expected")),
        @AttributeOverride(name="semiFlexiRecorded", column=@Column(name="tuesday_semi_flexi_recorded")),
        @AttributeOverride(name="semiFlexiSickness", column=@Column(name="tuesday_semi_flexi_sickness")),
        @AttributeOverride(name="semiFlexiHoliday", column=@Column(name="tuesday_semi_flexi_holiday")),

        @AttributeOverride(name="flexiExpected", column=@Column(name="tuesday_flexi_expected")),
        @AttributeOverride(name="flexiRecorded", column=@Column(name="tuesday_flexi_recorded")),
        @AttributeOverride(name="flexiSickness", column=@Column(name="tuesday_flexi_sickness")),
        @AttributeOverride(name="flexiHoliday", column=@Column(name="tuesday_flexi_holiday")),

        @AttributeOverride(name="sessionExpected", column=@Column(name="tuesday_session_expected")),
        @AttributeOverride(name="sessionRecorded", column=@Column(name="tuesday_session_recorded")),
        @AttributeOverride(name="sessionSickness", column=@Column(name="tuesday_session_sickness")),
        @AttributeOverride(name="sessionHoliday", column=@Column(name="tuesday_session_holiday")),

        @AttributeOverride(name="adHocRecorded", column=@Column(name="tuesday_ad_hoc_recorded")),
        @AttributeOverride(name="adHocSickness", column=@Column(name="tuesday_ad_hoc_sickness")),
        @AttributeOverride(name="adHocHoliday", column=@Column(name="tuesday_ad_hoc_holiday"))
    })
    private AllocationOfHours tuesday;

    public AllocationOfHours getTuesday() {
        return tuesday;
    }

    public void setTuesday(AllocationOfHours tuesday) {
        AllocationOfHours oldTuesday = this.tuesday;
        this.tuesday = tuesday;
        changeSupport.firePropertyChange("tuesday", oldTuesday, tuesday);
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Wednesday Figures">
    @Embedded
    @AttributeOverrides({
        @AttributeOverride(name="clocked", column=@Column(name="wednesday_clocked")),
        @AttributeOverride(name="entered", column=@Column(name="wednesday_entered")),
        @AttributeOverride(name="sickness", column=@Column(name="wednesday_sickness")),
        @AttributeOverride(name="holiday", column=@Column(name="wednesday_holiday")),
        @AttributeOverride(name="estimated", column=@Column(name="wednesday_estimated")),

        @AttributeOverride(name="fixedExpected", column=@Column(name="wednesday_fixed_expected")),
        @AttributeOverride(name="fixedRecorded", column=@Column(name="wednesday_fixed_recorded")),
        @AttributeOverride(name="fixedSickness", column=@Column(name="wednesday_fixed_sickness")),
        @AttributeOverride(name="fixedHoliday", column=@Column(name="wednesday_fixed_holiday")),

        @AttributeOverride(name="semiFlexiExpected", column=@Column(name="wednesday_semi_flexi_expected")),
        @AttributeOverride(name="semiFlexiRecorded", column=@Column(name="wednesday_semi_flexi_recorded")),
        @AttributeOverride(name="semiFlexiSickness", column=@Column(name="wednesday_semi_flexi_sickness")),
        @AttributeOverride(name="semiFlexiHoliday", column=@Column(name="wednesday_semi_flexi_holiday")),

        @AttributeOverride(name="flexiExpected", column=@Column(name="wednesday_flexi_expected")),
        @AttributeOverride(name="flexiRecorded", column=@Column(name="wednesday_flexi_recorded")),
        @AttributeOverride(name="flexiSickness", column=@Column(name="wednesday_flexi_sickness")),
        @AttributeOverride(name="flexiHoliday", column=@Column(name="wednesday_flexi_holiday")),

        @AttributeOverride(name="sessionExpected", column=@Column(name="wednesday_session_expected")),
        @AttributeOverride(name="sessionRecorded", column=@Column(name="wednesday_session_recorded")),
        @AttributeOverride(name="sessionSickness", column=@Column(name="wednesday_session_sickness")),
        @AttributeOverride(name="sessionHoliday", column=@Column(name="wednesday_session_holiday")),

        @AttributeOverride(name="adHocRecorded", column=@Column(name="wednesday_ad_hoc_recorded")),
        @AttributeOverride(name="adHocSickness", column=@Column(name="wednesday_ad_hoc_sickness")),
        @AttributeOverride(name="adHocHoliday", column=@Column(name="wednesday_ad_hoc_holiday"))
    })
    private AllocationOfHours wednesday;

    public AllocationOfHours getWednesday() {
        return wednesday;
    }

    public void setWednesday(AllocationOfHours wednesday) {
        AllocationOfHours oldWednesday = this.wednesday;
        this.wednesday = wednesday;
        changeSupport.firePropertyChange("wednesday", oldWednesday, wednesday);
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Thursday Figures">
    @Embedded
    @AttributeOverrides({
        @AttributeOverride(name="clocked", column=@Column(name="thursday_clocked")),
        @AttributeOverride(name="entered", column=@Column(name="thursday_entered")),
        @AttributeOverride(name="sickness", column=@Column(name="thursday_sickness")),
        @AttributeOverride(name="holiday", column=@Column(name="thursday_holiday")),
        @AttributeOverride(name="estimated", column=@Column(name="thursday_estimated")),

        @AttributeOverride(name="fixedExpected", column=@Column(name="thursday_fixed_expected")),
        @AttributeOverride(name="fixedRecorded", column=@Column(name="thursday_fixed_recorded")),
        @AttributeOverride(name="fixedSickness", column=@Column(name="thursday_fixed_sickness")),
        @AttributeOverride(name="fixedHoliday", column=@Column(name="thursday_fixed_holiday")),

        @AttributeOverride(name="semiFlexiExpected", column=@Column(name="thursday_semi_flexi_expected")),
        @AttributeOverride(name="semiFlexiRecorded", column=@Column(name="thursday_semi_flexi_recorded")),
        @AttributeOverride(name="semiFlexiSickness", column=@Column(name="thursday_semi_flexi_sickness")),
        @AttributeOverride(name="semiFlexiHoliday", column=@Column(name="thursday_semi_flexi_holiday")),

        @AttributeOverride(name="flexiExpected", column=@Column(name="thursday_flexi_expected")),
        @AttributeOverride(name="flexiRecorded", column=@Column(name="thursday_flexi_recorded")),
        @AttributeOverride(name="flexiSickness", column=@Column(name="thursday_flexi_sickness")),
        @AttributeOverride(name="flexiHoliday", column=@Column(name="thursday_flexi_holiday")),

        @AttributeOverride(name="sessionExpected", column=@Column(name="thursday_session_expected")),
        @AttributeOverride(name="sessionRecorded", column=@Column(name="thursday_session_recorded")),
        @AttributeOverride(name="sessionSickness", column=@Column(name="thursday_session_sickness")),
        @AttributeOverride(name="sessionHoliday", column=@Column(name="thursday_session_holiday")),

        @AttributeOverride(name="adHocRecorded", column=@Column(name="thursday_ad_hoc_recorded")),
        @AttributeOverride(name="adHocSickness", column=@Column(name="thursday_ad_hoc_sickness")),
        @AttributeOverride(name="adHocHoliday", column=@Column(name="thursday_ad_hoc_holiday"))
    })
    private AllocationOfHours thursday;

    public AllocationOfHours getThursday() {
        return thursday;
    }

    public void setThursday(AllocationOfHours thursday) {
        AllocationOfHours oldThursday = this.thursday;
        this.thursday = thursday;
        changeSupport.firePropertyChange("thursday", oldThursday, thursday);
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Friday Figures">
    @Embedded
    @AttributeOverrides({
        @AttributeOverride(name="clocked", column=@Column(name="friday_clocked")),
        @AttributeOverride(name="entered", column=@Column(name="friday_entered")),
        @AttributeOverride(name="sickness", column=@Column(name="friday_sickness")),
        @AttributeOverride(name="holiday", column=@Column(name="friday_holiday")),
        @AttributeOverride(name="estimated", column=@Column(name="friday_estimated")),

        @AttributeOverride(name="fixedExpected", column=@Column(name="friday_fixed_expected")),
        @AttributeOverride(name="fixedRecorded", column=@Column(name="friday_fixed_recorded")),
        @AttributeOverride(name="fixedSickness", column=@Column(name="friday_fixed_sickness")),
        @AttributeOverride(name="fixedHoliday", column=@Column(name="friday_fixed_holiday")),

        @AttributeOverride(name="semiFlexiExpected", column=@Column(name="friday_semi_flexi_expected")),
        @AttributeOverride(name="semiFlexiRecorded", column=@Column(name="friday_semi_flexi_recorded")),
        @AttributeOverride(name="semiFlexiSickness", column=@Column(name="friday_semi_flexi_sickness")),
        @AttributeOverride(name="semiFlexiHoliday", column=@Column(name="friday_semi_flexi_holiday")),

        @AttributeOverride(name="flexiExpected", column=@Column(name="friday_flexi_expected")),
        @AttributeOverride(name="flexiRecorded", column=@Column(name="friday_flexi_recorded")),
        @AttributeOverride(name="flexiSickness", column=@Column(name="friday_flexi_sickness")),
        @AttributeOverride(name="flexiHoliday", column=@Column(name="friday_flexi_holiday")),

        @AttributeOverride(name="sessionExpected", column=@Column(name="friday_session_expected")),
        @AttributeOverride(name="sessionRecorded", column=@Column(name="friday_session_recorded")),
        @AttributeOverride(name="sessionSickness", column=@Column(name="friday_session_sickness")),
        @AttributeOverride(name="sessionHoliday", column=@Column(name="friday_session_holiday")),

        @AttributeOverride(name="adHocRecorded", column=@Column(name="friday_ad_hoc_recorded")),
        @AttributeOverride(name="adHocSickness", column=@Column(name="friday_ad_hoc_sickness")),
        @AttributeOverride(name="adHocHoliday", column=@Column(name="friday_ad_hoc_holiday"))
    })
    private AllocationOfHours friday;

    public AllocationOfHours getFriday() {
        return friday;
    }

    public void setFriday(AllocationOfHours friday) {
        AllocationOfHours oldFriday = this.friday;
        this.friday = friday;
        changeSupport.firePropertyChange("friday", oldFriday, friday);
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Saturday Figures">
    @Embedded
    @AttributeOverrides({
        @AttributeOverride(name="clocked", column=@Column(name="saturday_clocked")),
        @AttributeOverride(name="entered", column=@Column(name="saturday_entered")),
        @AttributeOverride(name="sickness", column=@Column(name="saturday_sickness")),
        @AttributeOverride(name="holiday", column=@Column(name="saturday_holiday")),
        @AttributeOverride(name="estimated", column=@Column(name="saturday_estimated")),

        @AttributeOverride(name="fixedExpected", column=@Column(name="saturday_fixed_expected")),
        @AttributeOverride(name="fixedRecorded", column=@Column(name="saturday_fixed_recorded")),
        @AttributeOverride(name="fixedSickness", column=@Column(name="saturday_fixed_sickness")),
        @AttributeOverride(name="fixedHoliday", column=@Column(name="saturday_fixed_holiday")),

        @AttributeOverride(name="semiFlexiExpected", column=@Column(name="saturday_semi_flexi_expected")),
        @AttributeOverride(name="semiFlexiRecorded", column=@Column(name="saturday_semi_flexi_recorded")),
        @AttributeOverride(name="semiFlexiSickness", column=@Column(name="saturday_semi_flexi_sickness")),
        @AttributeOverride(name="semiFlexiHoliday", column=@Column(name="saturday_semi_flexi_holiday")),

        @AttributeOverride(name="flexiExpected", column=@Column(name="saturday_flexi_expected")),
        @AttributeOverride(name="flexiRecorded", column=@Column(name="saturday_flexi_recorded")),
        @AttributeOverride(name="flexiSickness", column=@Column(name="saturday_flexi_sickness")),
        @AttributeOverride(name="flexiHoliday", column=@Column(name="saturday_flexi_holiday")),

        @AttributeOverride(name="sessionExpected", column=@Column(name="saturday_session_expected")),
        @AttributeOverride(name="sessionRecorded", column=@Column(name="saturday_session_recorded")),
        @AttributeOverride(name="sessionSickness", column=@Column(name="saturday_session_sickness")),
        @AttributeOverride(name="sessionHoliday", column=@Column(name="saturday_session_holiday")),

        @AttributeOverride(name="adHocRecorded", column=@Column(name="saturday_ad_hoc_recorded")),
        @AttributeOverride(name="adHocSickness", column=@Column(name="saturday_ad_hoc_sickness")),
        @AttributeOverride(name="adHocHoliday", column=@Column(name="saturday_ad_hoc_holiday"))
    })
    private AllocationOfHours saturday;

    public AllocationOfHours getSaturday() {
        return saturday;
    }

    public void setSaturday(AllocationOfHours saturday) {
        AllocationOfHours oldSaturday = this.saturday;
        this.saturday = saturday;
        changeSupport.firePropertyChange("saturday", oldSaturday, saturday);
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Sunday Figures">
    @Embedded
    @AttributeOverrides({
        @AttributeOverride(name="clocked", column=@Column(name="sunday_clocked")),
        @AttributeOverride(name="entered", column=@Column(name="sunday_entered")),
        @AttributeOverride(name="sickness", column=@Column(name="sunday_sickness")),
        @AttributeOverride(name="holiday", column=@Column(name="sunday_holiday")),
        @AttributeOverride(name="estimated", column=@Column(name="sunday_estimated")),

        @AttributeOverride(name="fixedExpected", column=@Column(name="sunday_fixed_expected")),
        @AttributeOverride(name="fixedRecorded", column=@Column(name="sunday_fixed_recorded")),
        @AttributeOverride(name="fixedSickness", column=@Column(name="sunday_fixed_sickness")),
        @AttributeOverride(name="fixedHoliday", column=@Column(name="sunday_fixed_holiday")),

        @AttributeOverride(name="semiFlexiExpected", column=@Column(name="sunday_semi_flexi_expected")),
        @AttributeOverride(name="semiFlexiRecorded", column=@Column(name="sunday_semi_flexi_recorded")),
        @AttributeOverride(name="semiFlexiSickness", column=@Column(name="sunday_semi_flexi_sickness")),
        @AttributeOverride(name="semiFlexiHoliday", column=@Column(name="sunday_semi_flexi_holiday")),

        @AttributeOverride(name="flexiExpected", column=@Column(name="sunday_flexi_expected")),
        @AttributeOverride(name="flexiRecorded", column=@Column(name="sunday_flexi_recorded")),
        @AttributeOverride(name="flexiSickness", column=@Column(name="sunday_flexi_sickness")),
        @AttributeOverride(name="flexiHoliday", column=@Column(name="sunday_flexi_holiday")),

        @AttributeOverride(name="sessionExpected", column=@Column(name="sunday_session_expected")),
        @AttributeOverride(name="sessionRecorded", column=@Column(name="sunday_session_recorded")),
        @AttributeOverride(name="sessionSickness", column=@Column(name="sunday_session_sickness")),
        @AttributeOverride(name="sessionHoliday", column=@Column(name="sunday_session_holiday")),

        @AttributeOverride(name="adHocRecorded", column=@Column(name="sunday_ad_hoc_recorded")),
        @AttributeOverride(name="adHocSickness", column=@Column(name="sunday_ad_hoc_sickness")),
        @AttributeOverride(name="adHocHoliday", column=@Column(name="sunday_ad_hoc_holiday"))
    })
    private AllocationOfHours sunday;

    public AllocationOfHours getSunday() {
        return sunday;
    }

    public void setSunday(AllocationOfHours sunday) {
        AllocationOfHours oldSunday = this.sunday;
        this.sunday = sunday;
        changeSupport.firePropertyChange("sunday", oldSunday, sunday);
    }
    // </editor-fold>

    @Column(name = "status")
    private WeeklyTimeStatus status;

    @JoinColumn(name = "employee_id", referencedColumnName = "employee_id", insertable = false, updatable = false)
    @ManyToOne(optional = false)
    private Employee employee;

    @JoinColumn(name = "administrator_id", referencedColumnName = "employee_id")
    @ManyToOne
    private Employee administrator;

    public WeeklyTime() {
        status = WeeklyTimeStatus.PREPARATION;
        monday = new AllocationOfHours();
        tuesday = new AllocationOfHours();
        wednesday = new AllocationOfHours();
        thursday = new AllocationOfHours();
        friday = new AllocationOfHours();
        saturday = new AllocationOfHours();
        sunday = new AllocationOfHours();
    }

    @PostLoad
    public void postLoad() {
        if (monday == null) {
            monday = new AllocationOfHours();
        }
        if (tuesday == null) {
            tuesday = new AllocationOfHours();
        }
        if (wednesday == null) {
            wednesday = new AllocationOfHours();
        }
        if (thursday == null) {
            thursday = new AllocationOfHours();
        }
        if (friday == null) {
            friday = new AllocationOfHours();
        }
        if (saturday == null) {
            saturday = new AllocationOfHours();
        }
        if (sunday == null) {
            sunday = new AllocationOfHours();
        }
    }

    public WeeklyTime(WeeklyTimePK weeklyTimePK) {
        this();
        this.weeklyTimePK = weeklyTimePK;
    }

    public WeeklyTime(int employeeId, Date weekCommencing) {
        this(new WeeklyTimePK(employeeId, weekCommencing));
    }

    public WeeklyTimePK getWeeklyTimePK() {
        return weeklyTimePK;
    }

    public void setWeeklyTimePK(WeeklyTimePK weeklyTimePK) {
        WeeklyTimePK oldWeeklyTimePK = this.weeklyTimePK;
        this.weeklyTimePK = weeklyTimePK;
        changeSupport.firePropertyChange("weeklyTimePK", oldWeeklyTimePK, weeklyTimePK);
    }

    public AllocationOfHours getDailyFigures(int dayOfWeek) {
        switch (dayOfWeek) {
            case GregorianCalendar.MONDAY:
                return this.monday;
            case GregorianCalendar.TUESDAY:
                return this.tuesday;
            case GregorianCalendar.WEDNESDAY:
                return this.wednesday;
            case GregorianCalendar.THURSDAY:
                return this.thursday;
            case GregorianCalendar.FRIDAY:
                return this.friday;
            case GregorianCalendar.SATURDAY:
                return this.saturday;
            case GregorianCalendar.SUNDAY:
                return this.sunday;
            default:
                return null;
        }
    }

    public AllocationOfHours getDailyFigures(GregorianCalendar cal) {
        return getDailyFigures(cal.get(GregorianCalendar.DAY_OF_WEEK));
    }

    public AllocationOfHours getWeeklyFigures(Integer dayOfWeek) {

        if (dayOfWeek == null) {
            dayOfWeek = GregorianCalendar.SUNDAY;
        }
        
        AllocationOfHours week = new AllocationOfHours();
        
        switch (dayOfWeek) {
            case GregorianCalendar.SUNDAY:
                week.add(sunday);
            case GregorianCalendar.SATURDAY:
                week.add(saturday);
            case GregorianCalendar.FRIDAY:
                week.add(friday);
            case GregorianCalendar.THURSDAY:
                week.add(thursday);
            case GregorianCalendar.WEDNESDAY:
                week.add(wednesday);
            case GregorianCalendar.TUESDAY:
                week.add(tuesday);
            case GregorianCalendar.MONDAY:
                week.add(monday);
        }
        
        return week;
    }

    // <editor-fold defaultstate="collapsed" desc="Clocked (calendar and day ordinal) Getters & Setters">
    public Double getClocked(int dayOfWeek) {
        return getDailyFigures(dayOfWeek).getClocked();
    }

    public Double getClocked(GregorianCalendar cal) {
        return getClocked(cal.get(GregorianCalendar.DAY_OF_WEEK));
    }

    public void setClocked(int dayOfWeek, Double clocked) {
        getDailyFigures(dayOfWeek).setClocked(clocked);
    }

    public void setClocked(GregorianCalendar cal, Double clocked) {
        setClocked(cal.get(GregorianCalendar.DAY_OF_WEEK), clocked);
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Entered (calendar and day ordinal) Getters & Setters">
    public Double getEntered(int dayOfWeek) {
        return getDailyFigures(dayOfWeek).getEntered();
    }

    public Double getEntered(GregorianCalendar cal) {
        return getEntered(cal.get(GregorianCalendar.DAY_OF_WEEK));
    }

    public void setEntered(int dayOfWeek, Double Entered) {
        getDailyFigures(dayOfWeek).setEntered(Entered);
    }

    public void setEntered(GregorianCalendar cal, Double Entered) {
        setEntered(cal.get(GregorianCalendar.DAY_OF_WEEK), Entered);
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Sickness (calendar and day ordinal) Getters & Setters">
    public Double getSickness(int dayOfWeek) {
        return getDailyFigures(dayOfWeek).getSickness();
    }

    public Double getSickness(GregorianCalendar cal) {
        return getSickness(cal.get(GregorianCalendar.DAY_OF_WEEK));
    };

    public void setSickness(int dayOfWeek, Double sickness) {
        getDailyFigures(dayOfWeek).setSickness(sickness);
    }

    public void setSickness(GregorianCalendar cal, Double sickness) {
        setSickness(cal.get(GregorianCalendar.DAY_OF_WEEK), sickness);
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Holiday (calendar and day ordinal) Getters & Setters">
    public Double getHoliday(int dayOfWeek) {
        return getDailyFigures(dayOfWeek).getHoliday();
    }

    public Double getHoliday(GregorianCalendar cal) {
        return getHoliday(cal.get(GregorianCalendar.DAY_OF_WEEK));
    }

    public void setHoliday(int dayOfWeek, Double holiday) {
        getDailyFigures(dayOfWeek).setHoliday(holiday);
    }

    public void setHoliday(GregorianCalendar cal, Double holiday) {
        setHoliday(cal.get(GregorianCalendar.DAY_OF_WEEK), holiday);
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="FixedExpected (calendar and day ordinal) Getters & Setters">
    public Double getFixedExpected(int dayOfWeek) {
        return getDailyFigures(dayOfWeek).getFixedExpected();
    }

    public Double getFixedExpected(GregorianCalendar cal) {
        return getFixedExpected(cal.get(GregorianCalendar.DAY_OF_WEEK));
    }

    public void setFixedExpected(int dayOfWeek, Double fixedExpected) {
        getDailyFigures(dayOfWeek).setFixedExpected(fixedExpected);
    }

    public void setFixedExpected(GregorianCalendar cal, Double fixedExpected) {
        setFixedExpected(cal.get(GregorianCalendar.DAY_OF_WEEK), fixedExpected);
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="FixedRecorded (calendar and day ordinal) Getters & Setters">
    public Double getFixedRecorded(int dayOfWeek) {
        return getDailyFigures(dayOfWeek).getFixedRecorded();
    }

    public Double getFixedRecorded(GregorianCalendar cal) {
        return getFixedRecorded(cal.get(GregorianCalendar.DAY_OF_WEEK));
    }

    public void setFixedRecorded(int dayOfWeek, Double fixedRecorded) {
        getDailyFigures(dayOfWeek).setFixedRecorded(fixedRecorded);
    }

    public void setFixedRecorded(GregorianCalendar cal, Double fixedRecorded) {
        setFixedRecorded(cal.get(GregorianCalendar.DAY_OF_WEEK), fixedRecorded);
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="SemiFlexiExpected (calendar and day ordinal) Getters & Setters">
    public Double getSemiFlexiExpected(int dayOfWeek) {
        return getDailyFigures(dayOfWeek).getSemiFlexiExpected();
    }

    public Double getSemiFlexiExpected(GregorianCalendar cal) {
        return getSemiFlexiExpected(cal.get(GregorianCalendar.DAY_OF_WEEK));
    }

    public void setSemiFlexiExpected(int dayOfWeek, Double semiFlexiExpected) {
        getDailyFigures(dayOfWeek).setSemiFlexiExpected(semiFlexiExpected);
    }

    public void setSemiFlexiExpected(GregorianCalendar cal, Double semiFlexiExpected) {
        setSemiFlexiExpected(cal.get(GregorianCalendar.DAY_OF_WEEK), semiFlexiExpected);
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="SemiFlexiRecorded (calendar and day ordinal) Getters & Setters">
    public Double getSemiFlexiRecorded(int dayOfWeek) {
        return getDailyFigures(dayOfWeek).getSemiFlexiRecorded();
    }

    public Double getSemiFlexiRecorded(GregorianCalendar cal) {
        return getSemiFlexiRecorded(cal.get(GregorianCalendar.DAY_OF_WEEK));
    }

    public void setSemiFlexiRecorded(int dayOfWeek, Double semiFlexiRecorded) {
        getDailyFigures(dayOfWeek).setSemiFlexiRecorded(semiFlexiRecorded);
    }

    public void setSemiFlexiRecorded(GregorianCalendar cal, Double semiFlexiRecorded) {
        setSemiFlexiRecorded(cal.get(GregorianCalendar.DAY_OF_WEEK), semiFlexiRecorded);

    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="FlexiExpected (calendar and day ordinal) Getters & Setters">
    public Double getFlexiExpected(int dayOfWeek) {
        return getDailyFigures(dayOfWeek).getFlexiExpected();
    }

    public Double getFlexiExpected(GregorianCalendar cal) {
        return getFlexiExpected(cal.get(GregorianCalendar.DAY_OF_WEEK));
    }

    public void setFlexiExpected(int dayOfWeek, Double flexiExpected) {
        getDailyFigures(dayOfWeek).setFlexiExpected(flexiExpected);
    }

    public void setFlexiExpected(GregorianCalendar cal, Double flexiExpected) {
        setFlexiExpected(cal.get(GregorianCalendar.DAY_OF_WEEK), flexiExpected);
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="FlexiRecorded (calendar and day ordinal) Getters & Setters">
    public Double getFlexiRecorded(int dayOfWeek) {
        return getDailyFigures(dayOfWeek).getFlexiRecorded();
    }

    public Double getFlexiRecorded(GregorianCalendar cal) {
        return getFlexiRecorded(cal.get(GregorianCalendar.DAY_OF_WEEK));
    }

    public void setFlexiRecorded(int dayOfWeek, Double flexiRecorded) {
        getDailyFigures(dayOfWeek).setFlexiRecorded(flexiRecorded);
    }

    public void setFlexiRecorded(GregorianCalendar cal, Double flexiRecorded) {
        setFlexiRecorded(cal.get(GregorianCalendar.DAY_OF_WEEK), flexiRecorded);
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="SessionExpected (calendar and day ordinal) Getters & Setters">
    public Double getSessionExpected(int dayOfWeek) {
        return getDailyFigures(dayOfWeek).getSessionExpected();
    }

    public Double getSessionExpected(GregorianCalendar cal) {
        return getSessionExpected(cal.get(GregorianCalendar.DAY_OF_WEEK));
    }

    public void setSessionExpected(int dayOfWeek, Double sessionExpected) {
        getDailyFigures(dayOfWeek).setSessionExpected(sessionExpected);
    }

    public void setSessionExpected(GregorianCalendar cal, Double sessionExpected) {
        setSessionExpected(cal.get(GregorianCalendar.DAY_OF_WEEK), sessionExpected);
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="SessionRecorded (calendar and day ordinal) Getters & Setters">
    public Double getSessionRecorded(int dayOfWeek) {
        return getDailyFigures(dayOfWeek).getSessionRecorded();
    }

    public Double getSessionRecorded(GregorianCalendar cal) {
        return getSessionRecorded(cal.get(GregorianCalendar.DAY_OF_WEEK));
    }

    public void setSessionRecorded(int dayOfWeek, Double sessionRecorded) {
        getDailyFigures(dayOfWeek).setSessionRecorded(sessionRecorded);
    }

    public void setSessionRecorded(GregorianCalendar cal, Double sessionRecorded) {
        setSessionRecorded(cal.get(GregorianCalendar.DAY_OF_WEEK), sessionRecorded);
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="AdHocRecorded (calendar and day ordinal) Getters & Setters">
    public Double getAdHocRecorded(int dayOfWeek) {
        return getDailyFigures(dayOfWeek).getAdHocRecorded();
    }

    public Double getAdHocRecorded(GregorianCalendar cal) {
        return getAdHocRecorded(cal.get(GregorianCalendar.DAY_OF_WEEK));
    }

    public void setAdHocRecorded(int dayOfWeek, Double adHocRecorded) {
        getDailyFigures(dayOfWeek).setAdHocRecorded(adHocRecorded);
    }

    public void setAdHocRecorded(GregorianCalendar cal, Double adHocRecorded) {
        setAdHocRecorded(cal.get(GregorianCalendar.DAY_OF_WEEK), adHocRecorded);
    }
    // </editor-fold>

    public WeeklyTimeStatus getStatus() {
        return status;
    }

    public void setStatus(WeeklyTimeStatus status) {
        WeeklyTimeStatus oldStatus = this.status;
        this.status = status;
        changeSupport.firePropertyChange("status", oldStatus, status);
    }

    public Employee getEmployee() {
        return employee;
    }

    public void setEmployee(Employee employee) {
        Employee oldEmployee = this.employee;
        this.employee = employee;
        changeSupport.firePropertyChange("employee", oldEmployee, employee);
    }

    public Employee getAdministrator() {
        return administrator;
    }

    public void setAdministrator(Employee administrator) {
        Employee oldAdministrator = this.administrator;
        this.administrator = administrator;
        changeSupport.firePropertyChange("administrator", oldAdministrator, administrator);
    }

    public boolean isEmpty() {

        return monday.getClocked() == 0 &&
                tuesday.getClocked() == 0 &&
                wednesday.getClocked() == 0 &&
                thursday.getClocked() == 0 &&
                friday.getClocked() == 0 &&
                saturday.getClocked() == 0 &&
                sunday.getClocked() == 0 &&
                monday.getEntered() == 0 &&
                tuesday.getEntered() == 0 &&
                wednesday.getEntered() == 0 &&
                thursday.getEntered() == 0 &&
                friday.getEntered() == 0 &&
                saturday.getEntered() == 0 &&
                sunday.getEntered() == 0;
    }

    public void setTotalClocked(Double dummy) {
        changeSupport.firePropertyChange("totalClocked", null, getTotalClocked());
    }

    public Double getTotalClocked() {
        Double total = null;
        for (int day = Calendar.SUNDAY; day < Calendar.SATURDAY; day++) {
            if (getClocked(day) != null) {
                if (total == null) {
                    total = getClocked(day);
                } else {
                    total += getClocked(day);
                }
            }
        }
        return total;
    }

    public void setTotalEntered(Double dummy) {
        changeSupport.firePropertyChange("totalEntered", null, getTotalEntered());
    }

    public Double getTotalEntered() {
        Double total = null;
        for (int day = Calendar.SUNDAY; day < Calendar.SATURDAY; day++) {
            if (getClocked(day) != null) {
                if (total == null) {
                    total = getEntered(day);
                } else {
                    total += getEntered(day);
                }
            }
        }
        return total;
    }

    public void setTotalHoliday(Double dummy) {
        changeSupport.firePropertyChange("totalHoliday", null, getTotalHoliday());
    }

    public Double getTotalHoliday() {
        Double total = null;
        for (int day = Calendar.SUNDAY; day < Calendar.SATURDAY; day++) {
            if (getHoliday(day) != null) {
                if (total == null) {
                    total = getHoliday(day);
                } else {
                    total += getHoliday(day);
                }
            }
        }
        return total;
    }

    public void setTotal(Double dummy) {
        changeSupport.firePropertyChange("total", null, getTotal());
    }

    public Double getTotal() {
        Double total = null;
        for (int day = Calendar.SUNDAY; day <= Calendar.SATURDAY; day++) {
            if (getEntered(day) != null) {
                if (total == null) {
                    total = getEntered(day);
                } else {
                    total += getEntered(day);
                }
            } else if (getClocked(day) != null) {
                if (total == null) {
                    total = getClocked(day);
                } else {
                    total += getClocked(day);
                }
            }
        }
        return total;
    }

    public void setTotalInclHoliday(Double dummy) {
        changeSupport.firePropertyChange("totalInclHoliday", null, getTotalInclHoliday());
    }

    public Double getTotalInclHoliday() {

        Double total = getTotal();
        Double totalHoliday = getTotalHoliday();

        if (total == null) {
            return totalHoliday;
        } else {
            if (totalHoliday == null) {
                return total;
            } else {
                return total + totalHoliday;
            }
        }
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (weeklyTimePK != null ? weeklyTimePK.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof WeeklyTime)) {
            return false;
        }
        WeeklyTime other = (WeeklyTime) object;
        if ((this.weeklyTimePK == null && other.weeklyTimePK != null) || (this.weeklyTimePK != null && !this.weeklyTimePK.equals(other.weeklyTimePK))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "TimeRecording.tables.WeeklyTime[weeklyTimePK=" + weeklyTimePK + "]";
    }

    public boolean inRange(Calendar startCal, Calendar endCal) {

        // If the end of the supplied period is before the week the bail out
        if (endCal.getTime().before(this.getWeeklyTimePK().getWeekCommencing())) {
            return false;
        }

        if (weekEnding == null) {
            GregorianCalendar endOfWeek = new GregorianCalendar();
            endOfWeek.setTime(this.getWeeklyTimePK().getWeekCommencing());
            endOfWeek = DaisyChainUtilities.lastDayOfWeek(endCal);
            weekEnding = endOfWeek.getTime();
        }

        if (startCal.getTime().after(weekEnding)) {
            return false;
        }

        return true;
    }

    public boolean inRange(Calendar cal) {
        return inRange(cal, cal);
    }

    public static List<WeeklyTime> getActiveWeeklyTimeByEmployee(
            EntityManager entityManager, Employee employee) {

        return entityManager.createNamedQuery(
                "WeeklyTime.findByEmployeeAndStatuses").
                setParameter("employeeId", employee.getEmployeeId()).
                setParameter("status1", WeeklyTimeStatus.APPROVED).
                setParameter("status2", WeeklyTimeStatus.PREPARATION).
                setParameter("status3", WeeklyTimeStatus.REJECTED).
                setParameter("status4", WeeklyTimeStatus.SUBMITTED).getResultList();
    }

    public static List<WeeklyTime> getWeeklyTimeByEmployeeAndDateRange(
            EntityManager entityManager, Employee employee, DateRange dateRange) {

        Date startOfFirstWeek = DaisyChainUtilities.
                firstDayOfWeek(dateRange.getFromDate());

        Date startOfLastWeek = DaisyChainUtilities.
                firstDayOfWeek(dateRange.getToDate());

        return entityManager.createNamedQuery(
                "WeeklyTime.findByEmployeeAndDateRange").
                setParameter("employeeId", employee.getEmployeeId()).
                setParameter("startDate", startOfFirstWeek).
                setParameter("endDate", startOfLastWeek).getResultList();
    }

    public static List<WeeklyTime> getActiveWeeklyTime(EntityManager entityManager) {

        return entityManager.createNamedQuery(
                "WeeklyTime.findByStatuses").
                setParameter("status1", WeeklyTimeStatus.APPROVED).
                setParameter("status2", WeeklyTimeStatus.PREPARATION).
                setParameter("status3", WeeklyTimeStatus.REJECTED).
                setParameter("status4", WeeklyTimeStatus.SUBMITTED).getResultList();
    }
}